﻿using DeHeng_Mes.Model.ConfigModel;
using DeHeng_Mes.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DeHeng_Mes.Utils;
using System.Reflection;
using DeHeng_Mes.Dao.PlcDao;
using DeHeng_Mes.Dao;
using DeHeng_Mes.Constant;

namespace DeHeng_Mes.Thread
{
    public class PlcCollectionData
    {
        #region 全局成员
        List<PlcOrderConfigModel> readPlcList = PlcOrderConfigModelList.ReadPlcList;
        Dictionary<string, Dictionary<string, bool>> saveStatus = StationSaveStatusDic.SaveStatus;
        LinePlcToMes LinePlcToMes = new LinePlcToMes();
        PlcDao plcDao = new PlcDao();
        #endregion

        /// <summary>
        /// Plc交互轮询
        /// </summary>
        /// <returns></returns>
        public async Task CollectionTask()
        {
            int timer = 10000;

            Tools.ProduceLogText("启动Plc交互线程成功！");

            while (true)
            {
                await Task.Delay(timer);
                timer = 1000;
                if (readPlcList != null && readPlcList.Count > 0)
                {
                    timer = 50;
                    //遍历订单模型，取出该模型下挂的所有Plc处理数据
                    foreach (var orderModel in readPlcList)
                    {
                        //判断当前订单模型是否处于处理状态，如果处于正在处理状态那么不会继续创建
                        if (!orderModel.IsProcessed)
                        {
                            // 正在处理中
                            orderModel.IsProcessed = true;

                            _ = Task.Run(async () =>
                            {
                                try
                                {

                                    // 获取Plc数据实例与实例类型
                                    Dictionary<object, Type> dictionary = MappingTable.PlcMapping(orderModel.plc, orderModel.PlcName);

                                    // 检查或处理工单前检查当前工单保存状态是否配置
                                    SaveInit(dictionary,orderModel);

                                    // 处理订单
                                    Task<bool> isOk = LinePlcToMes.OrderStatus(dictionary, orderModel);

                                    //完成工单，处理订单模型
                                    if (isOk.Result)
                                    {

                                        // 使用线程安全方式移除任务
                                        lock (readPlcList)
                                        {
                                            // 清除工单存储状态
                                            saveStatus.Remove(orderModel.orderPlan.OrderId);

                                            // 清除工单模型缓存
                                            readPlcList.Remove(orderModel);
                                        }

                                        if (readPlcList.Count > 0)
                                        {
                                            Tools.ProduceLogText($"未完成的订单还剩下{readPlcList.Count}个，持续生产中...");
                                        }
                                        else
                                        {
                                            Tools.ProduceLogText("订单已全部完成，监听工厂Mes下发新工单中...");
                                        }
                                    }
                                }
                                catch (TargetInvocationException ex)
                                {
                                    Tools.ProduceLogTextError(orderModel.PlcName + ":数据读取执行失败，原因是：" + ex.Message);
                                }
                                finally
                                {
                                    //处理结束
                                    orderModel.IsProcessed = false;
                                }
                            });
                        }
                    }
                }
            }
        }
   #region 私有方法
        /// <summary>
        /// 初始化或检查工位读取状态是否配置
        /// </summary>
        /// <param name="dictionary"></param>
        /// <param name="orderModel"></param>
        private void SaveInit(Dictionary<object, Type> dictionary, PlcOrderConfigModel orderModel)
        {
            try
            {
                // 获取Plc工位字段名称数据
                Dictionary<string, object> StationStatusDic = plcDao.GetFieldValues(dictionary, SystemConstant.StationStatus);

                // 初始化工位名称字段与状态字典
                Dictionary<string, bool> fieldKeyValuePairs = null;

                // 取出状态配置
                if (saveStatus.TryGetValue(orderModel.orderPlan.OrderId, out Dictionary<string, bool> statusValueDic))
                {
                    foreach (var StationStatus in StationStatusDic)
                    {
                        if (StationStatus.Key.Contains("Op") && !statusValueDic.ContainsKey(StationStatus.Key))
                            saveStatus[orderModel.orderPlan.OrderId].Add(StationStatus.Key, false);
                    }
                }
                else
                {
                    // 创建字段字典实例
                    fieldKeyValuePairs = new Dictionary<string, bool>();

                    // 配置字段字典数据
                    foreach (var StationStatus in StationStatusDic)
                    {
                        fieldKeyValuePairs.Add(StationStatus.Key, false);
                    }

                    saveStatus.Add(orderModel.orderPlan.OrderId, fieldKeyValuePairs);
                }
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"配置{orderModel.PlcName}工位读取状态失败，失败工单为{orderModel.orderPlan.OrderId}");
            }
        }
        #endregion    
    }
}
